package com.sky.JWT;

import com.auth0.jwt.interfaces.DecodedJWT;
import com.sky.entity.Employee;
import com.sky.service.ShiroUserService;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

import java.util.Collections;
import java.util.Objects;

@Component
public class JWTRealm extends AuthorizingRealm {

    @Autowired
    @Lazy
    private ShiroUserService employeeService;

    // 让shiro支持我们自定义的token，即如果传入的token时JWTToken则放行
    // 必须重写不然shiro会报错
    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof JWTToken;
    }

    // 检验权限时调用
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        DecodedJWT verify = JWTUtils.verify(principalCollection.toString());
        Long id = verify.getClaim("id").asLong();
        // 根据username查询用户的身份和权限
        Employee employee = employeeService.getById(id);
        String role="普通用户";
        if (Objects.equals(employee.getRole(), "1")){
            role="管理员";
            employee.setPermission((Collections.singletonList("管理员")));
        }
        if(Objects.equals(employee.getRole(), "2")){
            role="系统管理员";
            employee.setPermission((Collections.singletonList("系统管理员")));
        }
        if(Objects.equals(employee.getRole(), "0")){
            employee.setPermission((Collections.singletonList("普通用户")));
        }
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.addRole(role);
        info.addStringPermissions(employee.getPermission());
        return info;
    }

    // 认证和鉴权时调用
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String token = (String) authenticationToken.getCredentials();// 重写了该类，实际上返回的是token
        Long id = null;
        try {
            // 根据token获得登录用户的id
            id = JWTUtils.verify(token).getClaim("id").asLong();
        } catch (Exception e) {
            throw new AuthenticationException("该token非法，可能被篡改或过期");
        }
        if (employeeService.getById(id) == null) {
            throw new AuthenticationException("用户不存在");
        }
        return new SimpleAuthenticationInfo(token, token, this.getName());
    }
}
